/*
 * Professional Android, 4th Edition
 * Reto Meier and Ian Lake
 * Copyright 2018 John Wiley Wiley & Sons, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.professionalandroid.apps.earthquake;

import android.app.Application;
import android.arch.lifecycle.AndroidViewModel;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.MutableLiveData;
import android.content.SharedPreferences;
import android.location.Location;
import android.os.AsyncTask;
import android.os.Build;
import android.support.v7.preference.PreferenceManager;
import android.util.Log;
import android.widget.Toast;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

public class EarthquakeViewModel extends AndroidViewModel {
  private static final String TAG = "EarthquakeUpdate";

  private LiveData<List<Earthquake>> earthquakes;

  public EarthquakeViewModel(Application application) {
    super(application);
  }

  public LiveData<List<Earthquake>> getEarthquakes() {
    if (earthquakes == null) {
      // Load the Earthquakes from the database.
      earthquakes =
        EarthquakeDatabaseAccessor
          .getInstance(getApplication())
          .earthquakeDAO()
          .loadAllEarthquakes();

      loadEarthquakes();
    }
    return earthquakes;
  }
  // 从网络feed中异步加载地震。 Asynchronously load the Earthquakes from the feed.
  public void loadEarthquakes() {
    /**
     * 初版示例应用 FireBase Job Dispatcher 计划作业。在使用Android7.0(API级别24)及更高版本系统的设备上， FireBase Job Dispatcher 将调度作业的职责交给框
     * 架Job Scheduler。 Job Scheduler在Android5.0(API级别21)中引入，而 FireBase Job Dispatcher 是为Android4.0(API级别14)及更高版本系统的设备而开发的。
     *  FireBase Job Dispatcher 要求在设备上运行GooglePlay 服务！因此模拟机上可能无法正常工作。
     * 二版推送改用 Job Scheduler ，同时minSdkVersion 改为 21
     */
    int sdkInt=Build.VERSION.SDK_INT;
    if ( sdkInt>= Build.VERSION_CODES.LOLLIPOP)
    {
      com.professionalandroid.apps.myapplication.BackgroundJobService.scheduleEarthquakeUpdateJob(getApplication());
//      com.professionalandroid.apps.myapplication.BackgroundJobService.scheduleNextUpdate(getApplication());
    }else if (sdkInt >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
      EarthquakeUpdateJobService.scheduleUpdateJob(getApplication());
     }else
    {
//      todo test API级别低于14,换回老方法了要
        loadEarthquakesoldfunction();
     }

 }


  /**
   * 从网络feed中异步加载地震。 Asynchronously load the Earthquakes from the feed.
   */
  public void loadEarthquakesoldfunction(){
    Toast.makeText(getApplication(),"API级别低于14，建议更新。当前正在异步执行替代操作"  ,Toast.LENGTH_LONG).show();

        AsyncTask<Void, Void, Boolean> mJobTask;
        final String AsyncTaskTAG = "oldAsyncTask";
    // 在后台线程中执行其他工作。 // Execute additional work within a background thread.
      mJobTask = new AsyncTask<Void, Void, Boolean>() {
          @Override
          protected Boolean doInBackground(Void... voids) {
              //   Do your background work.





//加载地震数据！
              // Result ArrayList of parsed earthquakes.
              ArrayList<Earthquake> earthquakes = new ArrayList<>();
              // Get the XML
              URL url;
              try {
                  String quakeFeed = getApplication().getString(R.string.earthquake_feed);

                  url = new URL(quakeFeed);

                  URLConnection connection;
                  connection = url.openConnection();
                  HttpURLConnection httpConnection = (HttpURLConnection) connection;

                  int responseCode = httpConnection.getResponseCode();
                  if (responseCode == HttpURLConnection.HTTP_OK) {
                      InputStream in = httpConnection.getInputStream();
                      DocumentBuilderFactory dbf =
                              DocumentBuilderFactory.newInstance();
                      DocumentBuilder db = dbf.newDocumentBuilder();

                      // Parse the earthquake feed.
                      Document dom = db.parse(in);
                      Element docEle = dom.getDocumentElement();

                      // Get a list of each earthquake entry.
                      NodeList nl = docEle.getElementsByTagName("entry");
                      if (nl != null && nl.getLength() > 0) {
                          for (int i = 0; i < nl.getLength(); i++) {
                              Element entry =
                                      (Element) nl.item(i);
                              Element id =
                                      (Element) entry.getElementsByTagName("id").item(0);
                              Element title =
                                      (Element) entry.getElementsByTagName("title").item(0);
                              Element g =
                                      (Element) entry.getElementsByTagName("georss:point")
                                              .item(0);
                              Element when =
                                      (Element) entry.getElementsByTagName("updated").item(0);
                              Element link =
                                      (Element) entry.getElementsByTagName("link").item(0);

                              String idString = id.getFirstChild().getNodeValue();
                              String details = title.getFirstChild().getNodeValue();
                              String hostname = "";//http://earthquake.usgs.gov";
                              String linkString = hostname + link.getAttribute("href");
                              String point = g.getFirstChild().getNodeValue();
                              String dt = when.getFirstChild().getNodeValue();

                              SimpleDateFormat sdf =
                                      new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSS'Z'");
                              Date qdate = new GregorianCalendar(0, 0, 0).getTime();

                              try {
                                  qdate = sdf.parse(dt);
                              } catch (ParseException e) {
                                  Log.e(AsyncTaskTAG, "Date parsing exception.", e);
                              }

                              String[] location = point.split(" ");
                              Location l = new Location("dummyGPS");
                              l.setLatitude(Double.parseDouble(location[0]));
                              l.setLongitude(Double.parseDouble(location[1]));

                              String magnitudeString = details.split(" ")[1];
                              int end = magnitudeString.length() - 1;
                              double magnitude =
                                      Double.parseDouble(magnitudeString.substring(0, end));

                              if (details.contains("-"))
                                  details = details.split("-")[1].trim();
                              else
                                  details = "";

                              final Earthquake earthquake = new Earthquake(idString,
                                      qdate,
                                      details, l,
                                      magnitude,
                                      linkString);

                              // Add the new earthquake to our result array.
                              earthquakes.add(earthquake);
                          }
                      }
                  }
                  httpConnection.disconnect();


                  // Insert the newly parsed array of Earthquakes
                  EarthquakeDatabaseAccessor
                          .getInstance(getApplication())
                          .earthquakeDAO()
                          .insertEarthquakes(earthquakes);



                  return true;
              } catch (MalformedURLException e) {
                  Log.e(AsyncTaskTAG, "Malformed URL Exception", e);
                  return false;
              } catch (IOException e) {
                  Log.e(AsyncTaskTAG, "IO Exception", e);
                  return false;
              } catch (ParserConfigurationException e) {
                  Log.e(AsyncTaskTAG, "Parser Configuration Exception", e);
                  return false;
              } catch (SAXException e) {
                  Log.e(AsyncTaskTAG, "SAX Exception", e);
                  return false;
              }









              // Return true if the job succeeded or false if it should be rescheduled due to a transient failure
              //如果作业成功，则返回true；如果由于暂时性故障而应重新安排作业，则返回false
//        return true;
          }

          @Override
          protected void onPostExecute(Boolean success) {
          }
      };
      mJobTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);


  }





}